<?php

    require_once "DriverAccess.class.php";
    require_once "Message.class.php";
  
    /**
     * Abstraccion de la Base de Datos, nos permite establecer conexiones con diferentes
     * Bases de Datos, a su vez, nos ayuda a la hora de realizar la Persistencia de los
     * diversos Objetos que hereden de esta Class, de forma automatica, con una sencilla
     * configuracion se podran Persistir los datos del objeto, como asi tambien recuperarlos.
     *
     * @category cormo
     * @package Core
     * @author Germán Dario Peraferrer <gperaferrer@gmail.com>
     * @copyright Copyright (c) 2007 Germán Dario Peraferrer - Beetec
     * @version 1.0 Beta
     * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
     * @link http://code.google.com/p/cormoframework/
     * @link http://www.beetec.com.ar
     */
    class Access {

        static private $PDOInstance;
        private $Message;
   
        /**
         * Establecemos la Conexion con la Base de Datos utilizando el DriverAccess y
         * generando la UNICA Instancia de la Conexion.
         *
         * @return void
         */
        public function __construct($connection) {
    	
         // Manejo de Mensajes
         $this->Message = new Message();
     
         // Inicializamos el Driver
         DriverAccess::init($connection);

         // Controlamos si se han establecido los valores de la configuracion de conexion.
         if(DriverAccess::isValidConfig()) {
        
            try {

            	/*
            	 * Debido a la implementacion de Multi Conexiones, se debe eliminar la consulta por
                 * isConnected(), por esto nos permite reemplazar la instancia por la que esta siendo solicitada
            	 */
               	@self::setPDOInstance(new PDO(DriverAccess::getDsn(),
                                           DriverAccess::getUser(),
                                           DriverAccess::getPassword(),
                                           array(PDO::ATTR_PERSISTENT => DriverAccess::getPersistent())) );

            } catch (PDOException $e) {
              die("Access Error durante el intento de Conexion: " . $e->getMessage() . "<br>");
            }
        
            return self::getPDOInstance();
       
          } else  {
            die("Access Error: El DriverAccess no posee los datos necesarios para establecer la Conexion.<br>");
          }
     
        }
    
        /**
         * Devuelve la Instancia del Objeto de mensajes
         *
         * @return Message
         */
        public function Message()	{
            return $this->Message;
        }
    
        /**
         * Devuelve el ultimo Mensaje que se ha producido en la Conexion
         *
         * @return string
         */
        public function getMessage()	{
        	return $this->Message()->getMessage();
        }
    
        /**
         * Asigna un Mensaje a la Conexion
         *
         * @param String $msg
         */
        public function setMessage($msg)	{
            $this->Message()->setMessage($msg);
        }
    
        /**
         * Retorna la Instancia a la Conexion de la Base de Datos.
         *
         * @return PDO
         */
        public static function getPDOInstance()  {
          return self::$PDOInstance;
        }
    
        /**
         * Asignamos la Instancia a la Conexion de la Base de Datos.
         *
         * @param PDO $instance
         * @return void
         */
        private function setPDOInstance(PDO $instance)  {
          self::$PDOInstance = $instance;
        }

        /**
         * Verifica y notifica si se ha creado el Objeto PDO cuando se intento la Conexion
         *
         * @return bool
         */
        public static function isConnected() {
          if(!self::getPDOInstance())
            return false;
          else
            return true;
        }
     
        /**
         * Initiates a transaction
         *
         * @return bool
         */
        public function beginTransaction() {
        	// Verificamos si el Driver Soporta Transacciones
            try	{
                $return = self::getPDOInstance()->beginTransaction();
        		$this->Message()->setMessage("Access: Transaccion Inicializada.");
        	} catch (PDOException $e)	{
            	$return = 1;
                $this->Message()->setMessage("Access: Warnning, el driver [".DriverAccess::getConfig()->getType()."] no soporta Transacciones.");
        	}
          return $return;
        }
        
        /**
         * Commits a transaction
         *
         * @return bool
         */
        public function commit() {
        	// Verificamos si el Driver Soporta Transacciones
            try	{
                $return = self::getPDOInstance()->commit();
        		$this->Message()->setMessage("Access: Transaccion realizo Commit.");
        	} catch (PDOException $e)	{
            	$return = 1;
                $this->Message()->setMessage("Access: Warnning, el driver [".DriverAccess::getConfig()->getType()."] no soporta Transacciones.");
        	}
          return $return;
        }
  
        /**
         * Fetch the SQLSTATE associated with the last operation on the database handle
         *
         * @return string
         */
        public function errorCode() {
          return self::getPDOInstance()->errorCode();
        }
    
        /**
         * Fetch extended error information associated with the last operation on the database handle
         *
         * @return array
         */
        public function errorInfo() {
          return self::getPDOInstance()->errorInfo();
        }
    
        /**
         * Execute an SQL statement and return the number of affected rows
         *
         * @param string $statement
         */
        public static function exec($statement) {
          return self::getPDOInstance()->exec($statement);
        }
    
        /**
         * Retrieve a database connection attribute
         *
         * @param int $attribute
         * @return mixed
         */
        public function getAttribute($attribute) {
          return self::getPDOInstance()->getAttribute($attribute);
        }

        /**
         * Return an array of available PDO drivers
         *
         * @return array
         */
        public function getAvailableDrivers(){
          return Self::getPDOInstance()->getAvailableDrivers();
        }
    
        /**
         * Returns the ID of the last inserted row or sequence value
         *
         * @param string $name Name of the sequence object from which the ID should be returned.
         * @return string
         */
        public function lastInsertId($name) {
          return self::getPDOInstance()->lastInsertId($name);
        }
        
        /**
         * Prepares a statement for execution and returns a statement object
         *
         * @param string $statement A valid SQL statement for the target database server
         * @param array $driver_options Array of one or more key=>value pairs to set attribute values for the PDOStatement obj returned
         * @return PDOStatement
         */
        public function prepare ($statement, $driver_options=false) {
        if(!$driver_options) $driver_options=array();
        return self::getPDOInstance()->prepare($statement, $driver_options);
        }
    
        /**
         * Executes an SQL statement, returning a result set as a PDOStatement object
         *
         * @param string $statement
         * @return PDOStatement
         */
        public function query($statement) {
          return self::getPDOInstance()->query($statement);
        }
    
        /**
         * Execute query and return all rows in assoc array
         *
         * @param string $statement
         * @return array
         */
        public function queryFetchAllAssoc($statement) {
          return self::getPDOInstance()->query($statement)->fetchAll(PDO::FETCH_ASSOC);
        }
    
        /**
         * Execute query and return one row in assoc array
         *
         * @param string $statement
         * @return array
         */
        public function queryFetchRowAssoc($statement) {
          return self::getPDOInstance()->query($statement)->fetch(PDO::FETCH_ASSOC);
        }
    
        /**
         * Execute query and select one column only
         *
         * @param string $statement
         * @return mixed
         */
        public function queryFetchColAssoc($statement) {
          return self::getPDOInstance()->query($statement)->fetchColumn();
        }
    
        /**
         * Quotes a string for use in a query
         *
         * @param string $input
         * @param int $parameter_type
         * @return string
         */
        public function quote ($input, $parameter_type=0) {
          return self::getPDOInstance()->quote($input, $parameter_type);
        }
    
        /**
         * Rolls back a transaction
         *
         * @return bool
         */
        public function rollBack() {
        	// Verificamos si el Driver Soporta Transacciones
            try	{
        		$return = self::getPDOInstance()->rollBack();
        		$this->Message()->setMessage("Access: Transaccion realizo RollBack.");
        	} catch (PDOException $e)	{
        		$return = 1;
            	$this->Message()->setMessage("Access: Warnning, el driver [".DriverAccess::getConfig()->getType()."] no soporta Transacciones.");
        	}
          return $return;
        }
    
        /**
         * Set an attribute
         *
         * @param int $attribute
         * @param mixed $value
         * @return bool
         */
        public function setAttribute($attribute, $value  ) {
          return self::getPDOInstance()->setAttribute($attribute, $value);
        }
    }

?>